package net.youpoint.dao.impl;

import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import net.youpoint.dao.QuestionDao;
import net.youpoint.entity.CommentEntity;
import net.youpoint.entity.OptionEntity;
import net.youpoint.entity.QuestionEntity;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;

public class QuestionDaoImplTest {

	private static final String QUESTION_TEXT = "test question text?";
	private static final String OPTION1_TEXT = "opt1";
	private static final String OPTION2_TEXT = "opt2";
	private static final String COMMENT_TEXT = "comm";

	private final LocalServiceTestHelper helper = new LocalServiceTestHelper(
			new LocalDatastoreServiceTestConfig());

	@Before
	public void setUp() {
		this.helper.setUp();
	}

	@After
	public void tearDown() {
		this.helper.tearDown();
	}

	@Test
	public void testList() {

		final QuestionDao questionDao = new QuestionDaoImpl();

		final List<QuestionEntity> list = questionDao.list();
		final int initCount = filterTestQuestions(list).size();

		final QuestionEntity question = createQuestion();

		questionDao.save(question);

		final List<QuestionEntity> list2 = questionDao.list();
		final List<QuestionEntity> filteredQuestions = filterTestQuestions(list2);
		final int newCount = filteredQuestions.size();

		assertEquals("list count change is incorrect", initCount + 1, newCount);

		// ---
		for (final QuestionEntity tmp : filteredQuestions) {
			final List<OptionEntity> options = tmp.getOptions();

			boolean opt1Found = false;
			boolean opt2Found = false;

			for (final OptionEntity tmpOpt : options) {
				if (OPTION1_TEXT.equals(tmpOpt.getText())) {
					opt1Found = true;
				}

				if (OPTION2_TEXT.equals(tmpOpt.getText())) {
					opt2Found = true;
				}

			}

			assertEquals("option 1 not found", opt1Found, true);
			assertEquals("option 2 not found", opt2Found, true);

			boolean commFound = false;
			final List<CommentEntity> comments = tmp.getComments();
			for (final CommentEntity tmpComm : comments) {

				if (COMMENT_TEXT.equals(tmpComm.getText())) {
					commFound = true;
				}

			}

			assertEquals("comment not found", commFound, true);
		}

	}

	@Test
	public void testSave() {
		final QuestionDao questionDao = new QuestionDaoImpl();
		final int initSize = questionDao.list().size();

		final QuestionEntity question = createQuestion();

		questionDao.save(question);

		final int newSize = questionDao.list().size();

		assertEquals("save is incorrect", initSize + 1, newSize);
	}

	private static List<QuestionEntity> filterTestQuestions(
			final List<QuestionEntity> list) {
		final List<QuestionEntity> res = new ArrayList<QuestionEntity>();

		for (final QuestionEntity tmp : list) {
			if (QUESTION_TEXT.equals(tmp.getText())) {
				res.add(tmp);
			}
		}

		return res;
	}

	private static QuestionEntity createQuestion() {
		final QuestionEntity question = new QuestionEntity();

		question.setText(QUESTION_TEXT);
		question.setCreateDate(new Date());

		final OptionEntity opt1 = new OptionEntity();
		opt1.setText(OPTION1_TEXT);
		opt1.setPop(1);
		opt1.setQuestion(question);

		final OptionEntity opt2 = new OptionEntity();
		opt2.setText(OPTION2_TEXT);
		opt2.setPop(2);
		opt2.setQuestion(question);

		final CommentEntity comm = new CommentEntity();
		comm.setDate(new Date());
		comm.setText(COMMENT_TEXT);
		comm.setQuestion(question);

		question.getOptions().add(opt1);
		question.getOptions().add(opt2);

		question.getComments().add(comm);

		return question;
	}
}
